//this file is part of eMule
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


//#include "stdafx.h"
#include "wintypes.h"
#include "KnownFileList.h"
#include "opcodes.h"
#include "emule.h"

#include <wx/listimpl.cpp>
WX_DEFINE_LIST(KnownFileList);

CKnownFileList::CKnownFileList(char* in_appdir) {
	appdir = in_appdir;
	accepted = 0;
	requested = 0;
	transfered = 0;
	Init();
}

CKnownFileList::~CKnownFileList() {
	list_mut.Unlock();
	Clear();
}

bool CKnownFileList::Init() {
	CKnownFile* Record = 0; 
	CSafeFile file;
	/*try*/ {
		char* fullpath = new char[strlen(appdir)+10];
		strcpy(fullpath,appdir);
		strcat(fullpath,"known.met");
		if (!file.Open(fullpath,CFile::read)) {//CFile::modeRead|CFile::osSequentialScan)) {
			delete[] fullpath;
			return false;
		}
		delete[] fullpath;
		
		uint8 header;
		file.Read(&header,1);
		if (header != MET_HEADER) {
			file.Close();
			return false;
		}
		//CSingleLock sLock(&list_mut,true); // to make sure that its thread-safe
		wxMutexLocker sLock(list_mut);
		uint32 RecordsNumber;
		file.Read(&RecordsNumber,4);
		for (uint32 i = 0; i != RecordsNumber; i++) {
			Record =  new CKnownFile();
			Record->LoadFromFile(&file);
			//Add(Record);
			Append(Record);
		}
		//sLock.Unlock();
		file.Close();
		return true;
	}
#if 0
	catch(CFileException* error) {
		if (error->m_cause == CFileException::endOfFile)
			theApp.emuledlg->AddLogLine(true,GetResString(IDS_ERR_SERVERMET_BAD));
		else{
			char buffer[150];
			error->GetErrorMessage(buffer,150);
			theApp.emuledlg->AddLogLine(true,GetResString(IDS_ERR_SERVERMET_UNKNOWN),buffer);
		}
		error->Delete();	//memleak fix
		return false;
	}
#endif
}

void CKnownFileList::Save() {
	FILE* file = 0;
	char* fullpath = new char[strlen(appdir)+MAX_PATH];
	strcpy(fullpath,appdir);
	strcat(fullpath,"known.met");
	if (!(file = fopen(fullpath, "wb"))) {
		delete[] fullpath;
		fullpath=NULL;
		return;
	}
	delete[] fullpath;
	fullpath=NULL;

	fputc(MET_HEADER,file);
	uint32 RecordsNumber = GetCount();
	fwrite(&RecordsNumber,4,1,file);
	for (uint32 i = 0; i < RecordsNumber; i++) {
		Item(i)->GetData()->WriteToFile(file);
	}
	fclose(file);
}

void CKnownFileList::Clear() {
	for (int i = 0; i != GetCount();i++)
	 free(Item(i)->GetData());
	KnownFileList::Clear();//RemoveAll();
	//SetSize(0);
}

CKnownFile* CKnownFileList::FindKnownFile(char* filename,uint32 in_date,uint32 in_size) {
	for (int i = 0;i != this->GetCount();i++) {
		if (Item(i)->GetData()->GetFileDate() == in_date && Item(i)->GetData()->GetFileSize() == in_size && (!strcmp(filename,Item(i)->GetData()->GetFileName())))
		  return Item(i)->GetData(); //ElementAt(i);
	}
	return 0;
}

void CKnownFileList::SafeAddKFile(CKnownFile* toadd) {
  //CSingleLock sLock(&list_mut,true);
//  wxMutexLocker sLock(list_mut);
  Append(toadd); //Add(toadd);
  //sLock.Unlock();
}
